#include "hnetdevice.h"
#include "sniffer/hnetdeviceprivate.h"

#include <QDebug>

HNetDevice::HNetDevice(QObject *parent) : QObject(parent)
{

}

bool HNetDevice::initDeviceInfo()
{
    Q_D(HNetDevice);
    if (d->m_allNetDevice == nullptr) {
        if (d->findAllDevs() == false) {
            return false;
        }
    }

    pcap_if_t	*index;
    pcap_addr_t *pAddr;
    DeviceInfo	tmpNetDevInfo;
    char ip6str[128];

    for (index = d->m_allNetDevice; index != nullptr; index = index->next) {
        tmpNetDevInfo.strNetDevname = index->name;

        if (index->description) {
            tmpNetDevInfo.strNetDevDescribe = "             ";
            tmpNetDevInfo.strNetDevDescribe += index->description;
        } else {
            tmpNetDevInfo.strNetDevDescribe = "             (No description available)";
        }

        for (pAddr = index->addresses; pAddr != nullptr; pAddr = pAddr->next) {
            switch(pAddr->addr->sa_family) {
            case AF_INET:
                tmpNetDevInfo.strIPV4FamilyName = "                  Address Family Name : ";
                tmpNetDevInfo.strIPV4FamilyName += "AF_INET (IPV4)";
                if (pAddr->addr) {
                    tmpNetDevInfo.strIPV4Addr = "                  IPV4 Address : ";
                    tmpNetDevInfo.strIPV4Addr += d->ipToString(((struct sockaddr_in *)pAddr->addr)->sin_addr.s_addr);
                }
                break;
            case AF_INET6:
                tmpNetDevInfo.strIPV6FamilyName = "                  Address Family Name : ";
                tmpNetDevInfo.strIPV6FamilyName += "AF_INET6 (IPV6)";
                if (pAddr->addr) {
                    tmpNetDevInfo.strIPV6Addr = "                  IPV6 Address : ";
                    tmpNetDevInfo.strIPV6Addr += d->ip6ToString(pAddr->addr, ip6str, sizeof(ip6str));
                }
                break;
            default:
                break;
            }
        }
        m_deviceInfo.push_back(tmpNetDevInfo);
    }

    return true;
}

int HNetDevice::captureOnce()
{
    Q_D(HNetDevice);
    if (d->m_currentDevice == nullptr) {
        return -2;
    }

    return pcap_next_ex(d->m_currentDevice, &d->m_header, &d->m_pktData);
}


void HNetDevice::printDevsInfo()
{
    for (QVector<DeviceInfo>::iterator index = m_deviceInfo.begin();
            index < m_deviceInfo.end(); ++index) {
        qInfo() << index->strNetDevname << "\n" << index->strNetDevDescribe << "\n"
                << index->strIPV4FamilyName << "\n" << index->strIPV4Addr << "\n"
                << index->strIPV6FamilyName << "\n" << index->strIPV6Addr;
    }
}

QVector<DeviceInfo> HNetDevice::deviceInfo() const
{
    return m_deviceInfo;
}

QVector<DataInfo> HNetDevice::captureData() const
{
    return m_captureData;
}

